/**
 * Copyright (c) Software Institute of PKU
 * All rights reserved. 
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 */
package edu.pku.sei.modeler.editparts;

import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.EllipseAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.DirectEditPolicy;
import org.eclipse.gef.editpolicies.LayoutEditPolicy;
import org.eclipse.gef.palette.CreationToolEntry;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gef.requests.DirectEditRequest;

import edu.pku.sei.modeler.editpolicies.UMLDiagramGraphicalNodeEditPolicy;
import edu.pku.sei.modeler.figures.UseCaseFigure;
import edu.pku.sei.modeler.handler.ActionHandleManager;
import edu.pku.sei.modeler.model.common.AbstractFactory;
import edu.pku.sei.modeler.model.common.ModelRegistry;
import edu.pku.sei.modeler.model.structure.MetaNode;
import edu.pku.sei.modeler.model.structure.MetaShapeElement;
import edu.pku.sei.modeler.model.structure.StructureFactory;
import edu.pku.sei.modeler.model.uml.UseCases.ExtensionPoint;
import edu.pku.sei.modeler.model.uml.UseCases.UseCase;
import edu.pku.sei.modeler.ui.palette.MetaCreationFactory;
import edu.pku.sei.modeler.uml.commands.ChangeNameCommand;
import edu.pku.sei.modeler.uml.commands.usecase.CreateExtensionPointCommand;
import edu.pku.sei.modeler.uml.images.ImageProvider;
import edu.pku.sei.modeler.uml.modelHelper.ModelPackage;

/**
 * @generated
 * 
 */
public class UseCaseEditpart extends AbstractUMLNodeEditPart {

	// private static int count = 1;

	public UseCaseEditpart(MetaShapeElement model) {
		super(model);
	}

	public void activate() {
		super.activate();
		UseCase model = (UseCase) ((MetaNode) getModel()).getModelElement();

		for (Iterator iter = model.getExtensionPoint().iterator(); iter
				.hasNext();) {
			ExtensionPoint element = (ExtensionPoint) iter.next();
			element.addPropertyChangeListener(modelListener);

		}

	}

	public void deactivate() {
		UseCase model = (UseCase) ((MetaNode) getModel()).getModelElement();
		for (Iterator iter = model.getExtensionPoint().iterator(); iter
				.hasNext();) {
			ExtensionPoint element = (ExtensionPoint) iter.next();
			element.removePropertyChangeListener(modelListener);

		}
		super.deactivate();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
	 */
	protected IFigure createFigure() {
		Label header = new Label("GeneratedShape");
		UseCaseFigure figure = new UseCaseFigure();
		figure.add(header);
		return figure;
	}

	protected DirectEditPolicy createDirectEditPolicy() {
		return new DirectEditPolicy() {
			protected Command getDirectEditCommand(DirectEditRequest request) {
				return new ChangeNameCommand(getUseCase(), (String) request
						.getCellEditor().getValue());
			}

			protected void showCurrentEditValue(DirectEditRequest request) {
				IFigure fig = getDirectEditFigure();
				if (fig instanceof Label) {
					((Label) fig).setText(getUseCase().getName());
					fig.getUpdateManager().performUpdate();
				}
			}
		};
	}

	@Override
	protected EditPart createChild(Object model) {
		return super.createChild(model);
	}

	@Override
	protected IFigure getDirectEditFigure() {
		return ((UseCaseFigure) this.getFigure()).getNameLabel();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
	 */
	protected void createEditPolicies() {
		super.createEditPolicies();

		installEditPolicy(EditPolicy.LAYOUT_ROLE, new LayoutEditPolicy() {
			protected EditPolicy createChildEditPolicy(EditPart child) {
				return null;
			}

			protected Command getCreateCommand(CreateRequest request) {
				if (request != null) {
					String objectType = (String) request.getNewObjectType();
					if (objectType != null
							&& objectType
									.equals(ModelPackage.__EXTENSIONPOINT__)) {
						return new CreateExtensionPointCommand(getUseCase());
					}
				}
				return null;
			}

			protected Command getDeleteDependantCommand(Request request) {

				return null;
			}

			protected Command getMoveChildrenCommand(Request request) {
				return null;
			}
		});

		this.installActionHandle();
	}

	protected void handlePropertyChanged(PropertyChangeEvent event) {
		refreshVisuals();
		super.handlePropertyChanged(event);
	}

	private UseCase getUseCase() {
		return (UseCase) ((MetaNode) getModel()).getModelElement();
	}

	@SuppressWarnings("unchecked")
	protected void refreshVisuals() {
		UseCase modelEle = this.getUseCase();
		UseCaseFigure figure = (UseCaseFigure) getFigure();
		figure.setName(modelEle.getName());

		List<ExtensionPoint> extensionPoints = modelEle.getExtensionPoint();
		List<String> extensionNames = new ArrayList<String>();
		for (Iterator iterator = extensionPoints.iterator(); iterator.hasNext();) {
			ExtensionPoint extensionPoint = (ExtensionPoint) iterator.next();
			extensionNames.add(extensionPoint.getName());
		}
		figure.setExtensionPoints(extensionNames);

		super.refreshVisuals();
		// System.out.println("UseCaseFigure: " + figure.getBounds().width +
		// "  " + figure.getBounds().height);
	}

	public void setDescription(String newDes) {
		this.getUseCase().setDescription(newDes);
	}

	public String getDescription() {
		return this.getUseCase().getDescription();
	}

	protected void installActionHandle() {
		ActionHandleManager actionMngr = new ActionHandleManager(this);

		PaletteDrawer entries = new PaletteDrawer("creation tool");
		try {

			AbstractFactory modelFactory = ModelRegistry.getRegistry()
					.getFactory(this.getNode().getModel());

			StructureFactory sFactory = (StructureFactory) ModelRegistry
					.getRegistry().getStructureFactory(
							this.getNode().getModel());

			CreationToolEntry extensionPointToolEntry = new CreationToolEntry(
					ImageProvider.PROPERTY_IMAGE, "Add Extension Point",
					new MetaCreationFactory(true,
							ModelPackage.__EXTENSIONPOINT__, modelFactory,
							sFactory), ImageProvider
							.getImageDescriptor(ImageProvider.EXTEND_IMAGE),
					null);

			// CreationToolEntry operationToolEntry = new
			// CreationToolEntry(ImageProvider.OPERATION_IMAGE,
			// "Add New Operation", new MetaCreationFactory(
			// true, ModelPackage.__OPERATION__, modelFactory, sFactory),
			// ImageProvider
			// .getImageDescriptor(ImageProvider.OPERATION_IMAGE), null);

			entries.add(extensionPointToolEntry);
			// entries.add(operationToolEntry);
			actionMngr.addTool(entries, PositionConstants.SOUTH_EAST);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public ConnectionAnchor getSourceConnectionAnchor(
			ConnectionEditPart connection) {
		if (anchor == null)
			anchor = new EllipseAnchor(getFigure());
		return anchor;
	}

	public ConnectionAnchor getSourceConnectionAnchor(Request request) {
		if (anchor == null)
			anchor = new EllipseAnchor(getFigure());
		return anchor;
	}

	public ConnectionAnchor getTargetConnectionAnchor(
			ConnectionEditPart connection) {
		if (anchor == null)
			anchor = new EllipseAnchor(getFigure());
		return anchor;
	}

	public ConnectionAnchor getTargetConnectionAnchor(Request request) {
		if (anchor == null)
			anchor = new EllipseAnchor(getFigure());
		return anchor;
	}

}
